//
//  UserRequest.swift
//  Employee
//
//  Created by swordjoy on 2017/3/16.
//  Copyright © 2017年 remotevillage. All rights reserved.
//

import Foundation
import SwiftyJSON
import Moya

var Refresh_Token_Error = "1017"

struct UserRequest: LoginResultProtocol, DataResultProtocol {
  
  static let shared = UserRequest()
  
    func login(with loginModel: LoginModel, loginSuccess: @escaping VoidClosure, failure: VoidClosure? = nil) -> Cancellable? {
    
    guard LogHelper.verifyUsername(with: loginModel.username) else {
        failure?()
        return nil
    }
    guard LogHelper.verifyPassword(with: loginModel.password) else {
        failure?()
        return nil
    }
    
    // 如果请求cache里面有该请求,直接返回
    let requestKey = SJApp.functionKey()
    if let cacheCancle = GlobalConfig.requestCache[requestKey] { return cacheCancle }

    let cancle = UserProvider.request(UserAPI.login(username: loginModel.username, password: loginModel.password)) { (result) in
      GlobalConfig.requestCache.removeValue(forKey: requestKey)
      
      self.loginProtocol(with: result, loginSuccess: { (data) in
        let access_token = data["access_token"].stringValue
        let refresh_token = data["refresh_token"].stringValue
        
        // 保存token
        Token.shared.cacheToken(token: access_token, refreshToken: refresh_token)
        // 通过token请求用户信息
        UserRequest.shared.getOrglist(loginSuccess: {
            UserRequest.shared.getUserInfo(loginSuccess: loginSuccess, failure: failure)
        }, failure: failure)
        Account.userAccount = loginModel.username
        
        
        
      }, loginFailure: failure)
     
    }
    
    GlobalConfig.requestCache[requestKey] = cancle
    
    return cancle
  }
  
    /// 这里不可能出现多次点击和token失效,不判断
    func getOrglist(loginSuccess: @escaping VoidClosure, failure: VoidClosure? = nil) {
        UserProvider.request(UserAPI.orglist()) { (result) in
            self.dataProtocol(with: result, isHideHUD: false, success: { (data) in
                // 保存用户信息
                let newData = NSMutableDictionary.init(dictionary: User.userInfoDic ?? NSDictionary())
                if let arr = data.arrayValue.first {
                    newData["companyId"] = arr["companyId"].stringValue
                    newData["organization"] = arr["companyName"].stringValue
                    newData["communityName"] = arr["communityName"].stringValue
                }
                User.save(with: JSON.init(newData))
                loginSuccess()
            }, failure: failure)
        }
    }
    
    /// 这里不可能出现多次点击和token失效,不判断,获取列表
    func getOrgData(loginSuccess: @escaping ([OrgModel])->(), failure: VoidClosure? = nil) {
        UserProvider.request(UserAPI.orglist()) { (result) in
            self.dataProtocol(with: result, isHideHUD: false, success: { (data) in
                
                let arr = OrgModel.array(from: data.arrayValue)
                
                loginSuccess(arr)
                
            }, failure: failure)
        }
    }
    
    
    
    
    /// 这里不可能出现多次点击和token失效,不判断
    func getUserInfo(loginSuccess: @escaping VoidClosure, failure: VoidClosure? = nil) {
        UserProvider.request(UserAPI.getUserInfo()) { (result) in
            self.dataProtocol(with: result, isHideHUD: false, success: { (data) in
                // 保存用户信息
                let newData = NSMutableDictionary.init(dictionary: User.userInfoDic ?? NSDictionary())
                newData.addEntries(from: data.dictionaryObject ?? NSDictionary() as! [String : Any])
                User.save(with: JSON.init(newData))
                
                /*
                // 登录前先判断环信在线不,在线先退出
                if EMClient.shared().isLoggedIn {
                    EMClient.shared().logout(true)
                }
                // 环信登录
                EMClient.shared().login(withUsername: User.huanxinAccount, password: User.huanxinPassword, completion: { (info, error) in
                    SJApp.hideHUD()
                    if let _ = error {
                        SJApp.log("环信错误:" + error!.errorDescription)
                        SJHint.show("登录失败")
                        return
                    }
                    
                    // 登录完成,记录操作
                    EMClient.shared().options.isAutoLogin = true
                    loginSuccess()
                    Account.isLogin = true
                    UserRequest.shared.setPushAlias()
                })
 
                 */
                SJApp.hideHUD()
                loginSuccess()
                Account.isLogin = true
                UserRequest.shared.setPushAlias()
                
            }, failure: failure)
        }
    }
  
  func refreshToken(success: @escaping VoidClosure) -> Cancellable {
    let requestKey = SJApp.functionKey()
    if let cacheCancle = GlobalConfig.requestCache[requestKey] { return cacheCancle }
    
    let cancle = UserProvider.request(UserAPI.refreshToken()) { (result) in
      GlobalConfig.requestCache.removeValue(forKey: requestKey)
      
      switch result {
      case let .success(response):
        let json = JSON(data: response.data)
        let responseCode = json["responseCode"].stringValue
        
        if Refresh_Token_Error == responseCode {
            User.logoutClean()
            User.longTimeNotLogin()
            return
        }
        
        Token.shared.cacheToken(token: json["data"]["access_token"].stringValue, refreshToken: json["data"]["refresh_token"].stringValue)
        success()
      case let .failure(error):
        SJApp.log(error)
        SJHint.show("未知错误")
      }
      
    }
    
    GlobalConfig.requestCache[requestKey] = cancle
    return cancle
  }
  
  
  func getUserAddressBook(success: @escaping ([ChatUser]) -> Void) -> Cancellable {
  
    let requestKey = SJApp.functionKey()
    if let cacheCancle = GlobalConfig.requestCache[requestKey] { return cacheCancle }
    
    let cancle =  UserProvider.request(UserAPI.getUserAddressBook()) { (result) in
      
      GlobalConfig.requestCache.removeValue(forKey: requestKey)
      
      self.dataProtocol(with: result, success: { (data) in
        
        let chatUsers = ChatUser.array(from: data["elements"].arrayValue)
        success(chatUsers)
        
      }, overdue: { 
        
        let _ = UserRequest.shared.getUserAddressBook(success: success)
        
      }, failure: nil)
      
    }
    
    GlobalConfig.requestCache[requestKey] = cancle
    
    return cancle
    
  }
  
 func logout(success: @escaping VoidClosure,failure: VoidClosure? ) -> Cancellable {
    
    let requestKey = SJApp.functionKey()
    if let cacheCancle = GlobalConfig.requestCache[requestKey] { return cacheCancle }
    
    let cancle = UserProvider.request(UserAPI.logout()) { (result) in
      
      GlobalConfig.requestCache.removeValue(forKey: requestKey)
      
      self.dataProtocol(with: result, success: { (data) in
        /*
        EMClient.shared().logout(true, completion: { (error) in
          
          if let _ = error { return }
          
          success()
        })
        */
        success()
        
      }, overdue: {  let _ = UserRequest.shared.logout(success: success, failure: failure) }, failure: failure)
    }
    
    GlobalConfig.requestCache[requestKey] = cancle
    
    return cancle
    
  }
  
  // MARK: - 获取修改密码验证码
  
  func getModifyPasswordCode(phone: String) -> Cancellable {
    let requestKey = SJApp.functionKey()
    if let cacheCancle = GlobalConfig.requestCache[requestKey] { return cacheCancle }
    
    let cancle = UserProvider.request(UserAPI.getModifyPasswordCode(phone: phone)) { (result) in
      GlobalConfig.requestCache.removeValue(forKey: requestKey)
      
      self.dataProtocol(with: result, success: { (_) in }, failure: nil)
    }
    
    GlobalConfig.requestCache[requestKey] = cancle
    return cancle
  }
  
  // MARK: - 验证验证码
  
  func verifyCode(phone: String, code: String, success: @escaping VoidClosure) -> Cancellable {
    let requestKey = SJApp.functionKey()
    if let cacheCancle = GlobalConfig.requestCache[requestKey] { return cacheCancle }
    
    let cancle = UserProvider.request(UserAPI.verifyCode(phone: phone, code: code)) { (result) in
      GlobalConfig.requestCache.removeValue(forKey: requestKey)
      
      self.dataProtocol(with: result, success: { (_) in
        success()
      }, failure: nil)
    }
    
    GlobalConfig.requestCache[requestKey] = cancle
    return cancle
  }
  
  // MARK: - 重置验证码
  
  func resetPassword(phone: String, password: String, success: @escaping VoidClosure) -> Cancellable {
    let requestKey = SJApp.functionKey()
    if let cacheCancle = GlobalConfig.requestCache[requestKey] { return cacheCancle }
    
    let cancle = UserProvider.request(UserAPI.resetPassword(phone: phone, password: password)) { (result) in
      GlobalConfig.requestCache.removeValue(forKey: requestKey)
      
      self.dataProtocol(with: result, success: { (_) in
        success()
      }, failure: nil)
      
    }
    
    GlobalConfig.requestCache[requestKey] = cancle
    return cancle
  }
  
  func setPushAlias() {
    
    JPUSHService.registrationIDCompletionHandler({ (errorCode, registrationID) in
        guard let temp = registrationID else {
            Account.isSetPushAlias = false
            return
        }
        UserProvider.request(UserAPI.setPushAlias()) { (result) in
            self.dataProtocol(with: result, success: { (_) in
                let tags = Set.init(User.tags)
                
                JPUSHService.setAlias(temp + User.phone, completion: { (code, alias, sep) in
                    Account.isSetPushAlias = true
                }, seq: 998)

                JPUSHService.setTags(tags, completion: { (code, set, seq) in
                    Account.isSetPushAlias = true
                }, seq: 999)
                

//                JPUSHService.setTags(tags, alias: temp + User.phone, fetchCompletionHandle: { (code, set, alias) in
//                    if code == 0 {
//                        Account.isSetPushAlias = true
//                        SJApp.log("\(code) + \(String(describing: set)) + \(String(describing: alias))")
//                    }
//                })
                
            }, failure: nil)
        }
    })
  }
  
  func getNotice(page: String, success: @escaping ( (([Notice], PageModel) -> Void)), failure: @escaping VoidClosure) -> Cancellable{
    
    let requestKey = SJApp.functionKey()
    if let cacheCancle = GlobalConfig.requestCache[requestKey] { return cacheCancle }
    
    let cancle = UserProvider.request(UserAPI.getNotice(page: page)) { (result) in
      GlobalConfig.requestCache.removeValue(forKey: requestKey)
      
      self.dataProtocol(with: result, success: { (data) in
        
        let notices = Notice.array(from: data["elements"].arrayValue)
        let page = PageModel(json: data)
        success(notices, page)
      }, overdue: {  let _ = UserRequest.shared.getNotice(page: page, success: success, failure: failure) },
         failure: failure)
    }
    
    GlobalConfig.requestCache[requestKey] = cancle
    return cancle
  }
  
    // MARK: - 获取区域
    func getRegion(success:@escaping ( ([RegionModel]) -> Void), failure: VoidClosure? = nil) -> Cancellable {
        let requestKey = SJApp.functionKey()
        if let cacheCancle = GlobalConfig.requestCache[requestKey] { return cacheCancle }
        
        let cancle = UserProvider.request(UserAPI.getRegion) { (result) in
            GlobalConfig.requestCache.removeValue(forKey: requestKey)
            self.dataProtocol(with: result, success: { (data) in
                let regions = RegionModel.array(from: data.arrayValue)
                success(regions)
            }, overdue: {
                let _ = UserRequest.shared.getRegion(success: success, failure: failure)
            }, failure: failure)
        }
        
        GlobalConfig.requestCache[requestKey] = cancle
        return cancle
    }
    
    // MARK: - 获取单元下的房间
    func getUnitHouse(regionId: String, success: @escaping ( ([House]) -> Void ), failure: @escaping VoidClosure) -> Cancellable {
        let cancle = UserProvider.request(UserAPI.getUnitHouse(regionId: regionId)) { (result) in
            self.dataProtocol(with: result, success: { (data) in
                let houses = House.array(from: data.arrayValue)
                success(houses)
            }, overdue: {
                let _ = UserRequest.shared.getUnitHouse(regionId: regionId, success: success, failure: failure)
            }, failure: failure)
        }
        return cancle
    }
    
    
    
}
